package classes {
	import MLP.mlp_effectLayer;
	
	import UIFree.uif_ecomponent;
	import UIFree.uif_loader;
	
	import flash.display.Bitmap;
	import flash.display.BitmapData;
	import flash.display.DisplayObject;
	import flash.display.Loader;
	import flash.display.LoaderInfo;
	import flash.display.Sprite;
	import flash.events.Event;
	import flash.filters.BitmapFilter;
	import flash.geom.Matrix;
	import flash.geom.Matrix3D;
	import flash.geom.Point;
	import flash.geom.Rectangle;
	import flash.geom.Vector3D;
	import flash.system.Security;

	public class c_util {
		private static var _policyFiles: Array = [];
		public static const POINT0: Point = new Point();
		
		public static function isHoleObject(source: DisplayObject): Boolean {
			var asLoader: Loader = source as Loader;
			return asLoader && (asLoader.content as Bitmap) && (asLoader.content as Bitmap).bitmapData.transparent;
		}
		
		public static function loadPolicyFile(file_url: String): void {
			if (_policyFiles.indexOf(file_url) == -1) {
				Security.loadPolicyFile(file_url);
				_policyFiles.push(file_url);
			}
		}
		
		public static function rotateMatrix(angle: Number, pivot: Point): Matrix {
			var mat: Matrix = new Matrix();
			mat.translate(-pivot.x, -pivot.y);
			mat.rotate(angle);
			mat.transformPoint(pivot);
			return mat;
		}
		
		public static function rotateComponent(component: uif_ecomponent, angle: Number, pivot: Point): void {
			var mat: Matrix = rotateMatrix(angle, pivot);
			mat.concat(component.transform.matrix);
			component.transform.matrix = mat; 
		}
		
		public static function round(value: Number, nums: int=2): Number {
			return Math.round(value * 10 * nums) / (10 * nums);
		}
		
		public static function findFilter(a_element: Sprite, filterClass: Class): BitmapFilter {
			var filters: Array = a_element.filters;
			for (var i: int; i<filters.length; i++) 
				if (filters[i] is filterClass) return filters[i];
			
			return null;
		}
		
		public static function invertMatrix(a_mat: Matrix): Matrix {
			var omat: Matrix = a_mat.clone();
			omat.invert();
			return omat;
		}
		
		public static function imagesRect(images: Array): Rectangle {
			var result: Rectangle = new Rectangle(int.MAX_VALUE, int.MAX_VALUE, int.MIN_VALUE, int.MIN_VALUE);
			images.forEach(function(item: DisplayObject, i: int, arr: Array): void {
				var rect: Rectangle = item.getBounds(item.parent);
				if (result.x > rect.x) result.x = rect.x;
				if (result.y > rect.y) result.y = rect.y;
				if (result.width < rect.width) result.width = rect.width;
				if (result.height < rect.height) result.height = rect.height;
			});
			return result;
		}
		
		public static function testSpotsOuter(spots: Array, bounds: Rectangle): Boolean {
			var srect: Rectangle = new Rectangle();
			spots.forEach(function(spot: Object, i: int, arr: Array): void {
				srect = srect.union(spot.bounds);
			});
			
			var _int: int = 0;
			if (srect.left == bounds.left) _int++;
			if (srect.right == bounds.right) _int++;
			if (srect.top == bounds.top) _int++;
			if (srect.bottom == bounds.bottom) _int++;
			return _int < 2;
		}
		
		public static function merge(images: Array): BitmapData {
			if (images.length > 0) {
				var rect	: Rectangle = c_util.imagesRect(images);
				var result	: BitmapData = new BitmapData(rect.width, rect.height, true, 0);
				images.forEach(function(item: DisplayObject, i: int, arr: Array): void {
					var mat: Matrix = item.transform.matrix.clone();
					result.draw(item, mat);
				});
				return result;
			} else return null;
		}
		
		public static function lookAt(point: Vector3D, target: Vector3D, up: Vector3D=null): Matrix3D {
			var _mat: Matrix3D = new Matrix3D();
			
			_mat.appendTranslation(point.x, point.y, point.z);
			_mat.pointAt(target, Vector3D.Z_AXIS, (up?up:(new Vector3D(0, -1, 0))));
			return _mat;
		}
		
		public static function SaturationArray(s: Number): Array{
			var rwgt: Number = .3086;
			var gwgt: Number = .6094;
			var bwgt: Number = .0820;
			var matrix: Array = [(1-s)*rwgt+s,  (1-s)*gwgt,      (1-s)*bwgt,            0,      0, 
				(1-s)*rwgt,     (1-s)*gwgt+s,   (1-s)*bwgt,            0,     0, 
				(1-s)*rwgt,     (1-s)*gwgt,       (1-s)*bwgt+s,        0,     0,
				0,                  0,                      0,                         1,     0];
			return matrix;
		}
		
		public static function fileExt(fileName: String): String {
			var i: int = fileName.indexOf('.', fileExt.length - 5);
			if (i > -1) return fileName.substr(i);
			return '';
		}
		
		public static function loadEffect(layer: mlp_effectLayer, effectURL: String, doComplete: Function=null): void {
			var loader: uif_loader = new uif_loader(null, effectURL, function(e: Event): void {
				var PJFilter: Class = (e.target as LoaderInfo).applicationDomain.getDefinition(layer.params.className?layer.params.className:'PJFilter');
				var _effect	: Object = new PJFilter();
				var scale	: Number = 1;
				_effect.parameters = {parent: layer, 
					bounds		: new Rectangle(0, 0, layer.width / scale, layer.height / scale), 
					info		: layer.params
				};
				if (doComplete != null) doComplete(_effect);
				loader.unload();
			});
		}
	}
}